package commonAdmin.sql.support;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.commons.lang3.StringUtils;

import commonAdmin.util.ObjectUtil;

/**
* 描述Model相关的表结构信息,维护类属性与表列之间的映射
* 
* @author dw_chenqi
* @date 2016年2月3日下午4:25:53
*/
public class ModelTableInfo {
	/** 默认表名前缀:t_ **/
	public static final String TABLE_PREFIX = "t_";

	private IdKey idKey;
	private String tableName;
	private List<FieldColumnMapper> fields;

	private Class<?> modelKlass;

	public ModelTableInfo(Class<?> modelKlass) {
		this.modelKlass = modelKlass;
		this.tableName = parseTableName();
		parseColumns();
	}

	private void parseColumns() {
		Field[] fields = modelKlass.getDeclaredFields();
		List<FieldColumnMapper> fieldInfos = new ArrayList<FieldColumnMapper>(fields.length);
		IdKey idKey = null;
		for (Field field : fields) {
			field.setAccessible(true);
			// 过滤@Transient注解与非基本类型+包装类型+String类型
			if (field.isAnnotationPresent(Transient.class) || !ObjectUtil.isPrimitiveOrPrimitiveWrapperOrString(field.getType()))
				continue;
			if (field.getName().equalsIgnoreCase("id") || field.isAnnotationPresent(Id.class)) {
				idKey = new IdKey(field);
				//fieldInfos.add(idKey);
			} else {
				fieldInfos.add(new FieldColumnMapper(field));
			}
		}
		if (idKey == null)
			throw new RuntimeException("Id property not found!Please make sure model has id field or add @Id! ");

		this.idKey = idKey;
		this.fields = fieldInfos;
	}

	private String parseTableName() {
		if (modelKlass.isAnnotationPresent(Table.class)) {
			Table table = (Table) modelKlass.getAnnotation(Table.class);
			if (StringUtils.isNotBlank(table.name()))
				return table.name();
		}
		return defaultTableName();
	}

	/**
	 * 以t开头,再加首字母小写加类名.例如:t_game
	 * @return
	 */
	private String defaultTableName() {
		String className = modelKlass.getSimpleName();
		StringBuilder tableName = new StringBuilder(className.length() + 2);
		return tableName.append(TABLE_PREFIX) //
				.append(Character.toLowerCase(className.charAt(0))) //
				.append(className.substring(1, className.length()))//
				.toString();

	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public List<FieldColumnMapper> getFields() {
		return fields;
	}

	public void setFields(List<FieldColumnMapper> fields) {
		this.fields = fields;
	}

	public IdKey getIdKey() {
		return idKey;
	}

	public void setIdKey(IdKey idKey) {
		this.idKey = idKey;
	}

}
